<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <script>
    function render() {
      console.log('模拟视图渲染');
    }
    let data = {
      name: '风里漂流',
      age: {
        age: 100
      },
      arr: [1, 2, 3],
      location: {
        x: 100,
        y: 100
      }
    }
    class Dep {
      constructor() {
        this.subs = []
      }
      addSub(sub) {
        this.subs.push(sub)
      }
      notify() {
        this.subs.forEach(sub => {
          sub.updata()
        })
      }
    }

    class Watcher {
      constructor(obj, key, cb) {
        Dep.target = this
        this.cb = cb
        this.obj = obj
        this.key = key
        // this.value = obj[key]
        Dep.target = null
      }
      updata() {
        this.value = this.obj[this.key]
        this.cb(this.value)
      }
    }
    // observe(data)
    function observe(obj) {
      if (!obj || typeof obj !== 'object') {
        return
      }
      Object.keys(obj).forEach(key => {
        defineReactive(obj, key, obj[key])
      })
      // 1. defineProperty
      function defineReactive(obj, key, value) {
        let dp = new Dep()
        Object.defineProperty(obj, key, {
          get: function () {
            console.log('get', value);
            if (Dep.target) {
              dp.addSub(Dep.target)
            }
            return value
          },
          set: function (newvalue) {
            console.log('set', newvalue);
            render()
            value = newvalue
            dp.notify()
          }
        })
      }
    }

    data.location = {
      x: 1000,
      y: 200
    }
    data.name

    // 2.proxy
    // let obj = {
    //   name: '风里漂流',
    //   age: {
    //     age: 100
    //   },
    //   arr: [1, 2, 3],
    // }
    // let handler = {
    //   get(target, key) {
    //     console.log('获取了值：get');
    //     if (typeof target[key] == 'object' && target[key] !== null) {
    //       return new Proxy(target[key], handler)
    //     }
    //     return Reflect.get(target, key)
    //   },
    //   set(target, key, value) {
    //     if (key === 'length') return true
    //     render()
    //     return Reflect.set(target, key, value)
    //   }
    // }
    // let proxy = new Proxy(obj, handler)
    // proxy.age.name = '我进步了'
    // console.log('--');
    // console.log(proxy.age.name);
    // console.log('--');
    // proxy.arr[0] = '110'
    // console.log('--');
    // console.log(proxy.arr);
    // console.log('--');
    // proxy.arr.length--



    class Vue {
      constructor(option) {
        this._data = option.data
        observe(this._data)
        new Watcher()
        console.log('模拟视图渲染');
      }
    }
    const el = new Vue(data)

  </script>
</body>

</html>